const path = require('path')
const fs = require('fs')
const { app, BrowserWindow, screen, Tray, Menu } = require('electron')

// 全局错误处理
const ERROR_LOG_FILE = path.join(path.dirname(app.getPath('exe')), 'error.log')
const LOG_FILE = path.join(path.dirname(app.getPath('exe')), 'app.log')

// 初始化日志文件
function initLogFiles() {
  try {
    if (!fs.existsSync(ERROR_LOG_FILE)) {
      fs.writeFileSync(ERROR_LOG_FILE, `[${new Date().toISOString()}] 错误日志初始化\n`)
    }
    if (!fs.existsSync(LOG_FILE)) {
      fs.writeFileSync(LOG_FILE, `[${new Date().toISOString()}] 应用日志初始化\n`)
    }
  } catch (err) {
    console.error('初始化日志文件失败:', err)
  }
}

// 记录日志
function logToFile(message, isError = false) {
  const logFile = isError ? ERROR_LOG_FILE : LOG_FILE
  const logMsg = `[${new Date().toISOString()}] ${message}\n`
  
  try {
    fs.appendFileSync(logFile, logMsg)
  } catch (err) {
    console.error('写入日志失败:', err)
  }
}

// 全局错误处理
process.on('uncaughtException', (err) => {
  const errorMsg = `未捕获的异常: ${err.stack || err}`
  console.error(errorMsg)
  logToFile(errorMsg, true)
  
  if (!tray) {
    // 如果主窗口或托盘图标未创建，直接退出应用
    app.quit()
  }
})

const express = require('express')

let mainWindow
let tray = null

// Electron应用设置
function createWindow () {
  mainWindow = new BrowserWindow({
    width: 1000,
    height: 600,
    webPreferences: {
      nodeIntegration: true
    },
    icon: path.join(__dirname, 'public/app-icon.png')
  })

  mainWindow.loadURL('http://localhost:3012')
  
  // 监听窗口最小化事件
  mainWindow.on('minimize', (event) => {
    event.preventDefault();
    mainWindow.hide();
  })

  // 监听窗口关闭事件
  mainWindow.on('close', (event) => {
    if (!app.isQuitting) {
      event.preventDefault();
      mainWindow.hide();
      return false;
    }
    return true;
  })

  mainWindow.on('closed', function () {
    mainWindow = null
  })
}

initLogFiles()
logToFile('应用启动')

app.whenReady().then(() => {
  // 创建系统托盘图标
  tray = new Tray(path.join(__dirname, 'public/app-icon.png'))
  const contextMenu = Menu.buildFromTemplate([
    {
      label: '显示窗口',
      click: () => {
        if (mainWindow === null) {
          createWindow()
        } else {
          mainWindow.show()
        }
      }
    },
    {
      label: '退出',
      click: () => {
        app.isQuitting = true;  // 设置退出标志
        app.quit()
      }
    }
  ])
  tray.setToolTip('Git合并提醒')
  tray.setContextMenu(contextMenu)
  
  // 修改双击事件处理
  tray.on('double-click', () => {
    if (mainWindow === null) {
      createWindow()
    } else {
      mainWindow.show()
    }
  })

  loadMonitors()
  createWindow()
})

app.on('window-all-closed', function () {
  if (process.platform !== 'darwin') {
    app.quit()
  }
})

app.on('activate', function () {
  if (mainWindow === null) createWindow()
})

const server = express()
const port = 3012
let monitors = []
const MONITORS_FILE = path.join(path.dirname(app.getPath('exe')), 'monitors.txt')

function loadMonitors() {
  try {
    if (fs.existsSync(MONITORS_FILE)) {
      const data = fs.readFileSync(MONITORS_FILE, 'utf8')
      if (!data) {
        return // 如果文件为空，则不加载任何数据，保持menitors为空数组
      }
      monitors = JSON.parse(data)
    }
  } catch (err) {
    console.error('加载监控数据失败:', err)
  }
}

function saveMonitors() {
  try {
    if (!fs.existsSync(MONITORS_FILE)) {
      fs.writeFileSync(MONITORS_FILE, '')
    }
    fs.writeFileSync(MONITORS_FILE, JSON.stringify(monitors))
  } catch (err) {
    console.error('保存监控数据失败:', err)
  }
}

// Express服务器设置
server.use(express.json())
server.use(express.static(path.join(__dirname, 'public')))

// API路由
server.get('/api/monitors', (req, res) => {
  console.log(`monitors: ${JSON.stringify(monitors)}`)
  res.json(monitors)
})

server.post('/api/monitors', (req, res) => {
  const { path, branch, name } = req.body
  const newMonitor = { path, branch, name }
  monitors.push(newMonitor)
  saveMonitors()
  checkMergeStatus(newMonitor)
  res.status(201).send()
})

server.delete('/api/monitors', (req, res) => {
  const { path, branch, name } = req.body
  monitors = monitors.filter(m => !(m.path === path && m.branch === branch && m.name === name))
  saveMonitors()
  res.status(204).send()
})

// 启动Express服务器
server.listen(port, () => {
  console.log(`Express server running at http://localhost:${port}`)
})

// 定时检查git合并状态
setInterval(() => {
  monitors.forEach(monitor => {
    checkMergeStatus(monitor)
  })
}, 60000)

function checkMergeStatus ({ path, branch, name }) {
  const { exec } = require('child_process')
  
  // 先执行git pull
  const pullCmd = process.platform === 'win32' 
    ? `cd /d ${path} && git pull`
    : `cd ${path} && git pull`
    
  // 然后单独检查合并状态
  const logCmd = process.platform === 'win32'
    ? `cd /d ${path} && git log origin/master --pretty=oneline | findstr "${branch}" | findstr "Merge branch '${branch}' into 'master'"`
    : `cd ${path} && git log origin/master --pretty=oneline | grep ${branch} | grep "Merge branch '${branch}' into 'master'"`
    
  console.log(`执行命令: ${logCmd}`) // 调试输出
  
  exec(pullCmd, (error) => {
    if (error) {
      console.error(`git pull失败: ${error}`)
      return
    }
    
    exec(logCmd, (error, stdout, stderr) => {
      console.log(`stdout: ${stdout}`) // 调试输出
      console.log(`stderr: ${stderr}`) // 调试输出
      
      if (stdout) {
        showNotification(path, branch, name)
        monitors = monitors.filter(m => !(m.path === path && m.branch === branch && m.name === name))
        mainWindow.webContents.reload()
      }
    })
  })
}

function showNotification (dir, branch, name) {
  const displayBounds = screen.getPrimaryDisplay().bounds;
  const notificationWindow = new BrowserWindow({
    width: 500,
    height: 500,
    x: displayBounds.width - 500 - 10,  // 增加10像素右边距
    y: displayBounds.height - 500 - 40, // 减去任务栏高度(约40像素)
    frame: false,
    alwaysOnTop: true,
    webPreferences: {
      nodeIntegration: true,
      contextIsolation: false,
    },
    show: false
  })
  
  notificationWindow.loadURL(`file://${path.join(__dirname, 'public/notification.html')}?name=${encodeURIComponent(name)}&path=${encodeURIComponent(dir)}&branch=${encodeURIComponent(branch)}`)
  notificationWindow.on('ready-to-show', () => {
    notificationWindow.show()
  })
}